package cn.edu.cqvie.grid;

import cn.edu.cqvie.point.Mobile3E;
import cn.edu.cqvie.point.Mobile3ESort;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * 移动端网格工具类
 */
@Log4j
public class Mobile3EGrid {

    public String m_key = null;

    /**
     * 坐标 Redis
     */
    private static StringRedisTemplate rc;
    /**
     * Token Redis
     */
    private static StringRedisTemplate br;

    /**
     * 获取周边终端
     *
     * @param x       中心点经度
     * @param y       中心点纬度
     * @param r_m
     * @param count   总数量
     * @param dstatus 司机状态
     * @param cartype 车辆类型
     * @return
     */
    public List<Mobile3E> getAllMobile(double x, double y, double r_m, int count, int dstatus, int cartype) throws Exception {
        int errindex = 1;
        if (count == 0) {
            count = 24;
        }
        if (dstatus == 0) {
            dstatus = -1;
        }
        if (cartype == 0) {
            cartype = -1;
        }
        try {
            errindex = 4;

            //检查redis登记矩阵，找出嫌疑，查询位置，没有位置的清除出矩阵，找出最近的24
            //int r = (int)(r_m / mobile3e.rect2km) + 1;
            double r = r_m * Mobile3E.jd_1m;
            int ix = 0;
            int iy = 0;
            int cx1 = Mobile3E.calcrectXId(x - r);
            int cx2 = Mobile3E.calcrectXId(x + r);
            int cy1 = Mobile3E.calcrectYId(y - r);
            int cy2 = Mobile3E.calcrectYId(y + r);

            errindex = 5;
            List<Mobile3ESort> ms = new ArrayList<Mobile3ESort>();

            for (ix = cx1; ix <= cx2; ix++) {
                for (iy = cy1; iy <= cy2; iy++) {
                    String ikey = Mobile3E.getRectIdStr(ix, iy);
                    List<Mobile3E> cachem3elist = new ArrayList<Mobile3E>(); // Redis_CacheGetHashSet(rc, br, ikey);

                    if (cachem3elist != null) {
                        for (Mobile3E m : cachem3elist) {
                            if (m.m_x == 0) continue;
                            Mobile3ESort sm = new Mobile3ESort();
                            sm.distance = Mobile3E.distance(x, y, m.m_x, m.m_y);
                            sm.m = m;
                            ms.add(sm);
                        }
                    }
                }
            }
            errindex = 6;
            //m3e.m_ltime = Convert.ToUInt32(m3e.distance(x, y));
            if (dstatus == -1 && cartype == -1) {

            } else {
                int i = 0;
                while (i < ms.size()) {
                    //去掉不合格的 ds 和 ct
                    boolean iiiok = true;
                    if (ms.get(i).m.m_x == 0) {
                        iiiok = false;
                    }
                    if (iiiok == true) {
                        if (dstatus == -1) {

                        } else {
                            if (ms.get(i).m.m_driverstatus == dstatus) {

                            } else {
                                iiiok = false;
                            }
                        }
                    }
                    if (iiiok == true) {
                        if (cartype == -1) {

                        } else {
                            if (ms.get(i).m.m_cartype == cartype) {

                            } else {
                                iiiok = false;
                            }
                        }
                    }

                    if (iiiok == false) {
                        ms.remove(i);
                        continue;
                    }

                    i++;
                }
            }

            errindex = 7;
            if (ms != null) {
                Collections.sort(ms, (s1, s2) -> s1.compareTo(s2));
                if (ms.size() > count) {
                    ms.subList(count, ms.size()).clear();
                }
            }
            errindex = 8;
            List<Mobile3E> ds = new ArrayList<Mobile3E>();
            for (Mobile3ESort m : ms) {
                ds.add(m.m);
            }

            return ds;

        } catch (Exception e) {
            log.error("GetAll " + m_key + " ErrIndex " + errindex, e);
            throw e;
        } finally {
        }
    }


    /**
     * 获取周边车辆
     *
     * @param skey
     * @return
     */
    public static List<Mobile3E> Redis_CacheGetHashSet(String skey) {//读取redis，优先取cache
        List<Mobile3E> cachem3elist = null;
        try {
            cachem3elist = MemoryCache.Default.Get(skey) as List<mobile3e >;
            if (cachem3elist == null) {
                HashSet<String> keyset = rc.GetAllItemsFromSet(skey);
                for (String key : keyset)
                {
                    Mobile3E m3e = Redis_CacheGetm3e(rc, br, key);
                    if (m3e == null) {
                        rc.RemoveItemFromSet(skey, key);
                        continue;
                    }

                    if (m3e.calcrectidstring() != skey) {
                        rc.RemoveItemFromSet(skey, key);
                        continue;
                    }
                    if (cachem3elist == null) cachem3elist = new List<mobile3e>();
                    cachem3elist.add(m3e);
                }
                if (cachem3elist == null) return null;

                CacheItemPolicy policy = new CacheItemPolicy();
                policy.AbsoluteExpiration = DateTime.Now.AddSeconds(60);
                MemoryCache.Default.Add(skey, cachem3elist, policy);
            } else {
                //更新列表中的位置，用于计算
                object a = MemoryCache.Default.Get(skey + " 10seconds");
                if (a == null) {
                    //查位置
                    int i = 0;
                    while (i < cachem3elist.size()) {
                        Mobile3E m = cachem3elist.get(i);
                        Mobile3E m3e = Redis_CacheGetm3e(rc, br, m.m_key);
                        if (m3e == null) {
                            //设置默认值
                            m.m_x = 0;
                            m.m_y = 0;
                            m.m_z = 0;
                            m.m_speed = 0;
                            m.m_direction = 0;
                        } else {
                            m.m_x = m3e.m_x;
                            m.m_y = m3e.m_y;
                            m.m_z = m3e.m_z;
                            m.m_speed = m3e.m_speed;
                            m.m_direction = m3e.m_direction;
                            m.m_driverstatus = m3e.m_driverstatus;
                            m.m_cartype = m3e.m_cartype;
                        }
                        i++;
                    }
                    CacheItemPolicy policy = new CacheItemPolicy();
                    policy.AbsoluteExpiration = DateTime.Now.AddSeconds(5);
                    MemoryCache.Default.Add(skey + " 10seconds", "10秒", policy);
                } else {
                    //直接用，10秒內核算过位置了
                }
            }
            return cachem3elist;
        } catch (Exception e) {
            throw e;
        }
        return cachem3elist;
    }


}
